package com.emmmya.ocs.modules.system.utils;

import com.alibaba.fastjson.JSONObject;
import com.sun.mail.util.MailSSLSocketFactory;
import com.emmmya.ocs.modules.system.setting.entity.Email;
import com.emmmya.ocs.modules.system.setting.entity.EmailProperties;
import com.emmmya.ocs.modules.system.setting.entity.Setting;
import com.emmmya.ocs.modules.system.setting.service.SettingService;
import com.emmmya.ocs.common.constant.SettingConstant;
import com.emmmya.ocs.common.exception.EmailException;
import com.emmmya.ocs.common.utils.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.util.StringUtils;

import javax.activation.DataSource;
import javax.mail.internet.MimeMessage;
import java.util.Map;
import java.util.Properties;

/**
 * @description:
 * @author: 咕噜肉IT小店-黑医
 * @createDate: 2020-05-13
 * @version: 1.0
 */
@Slf4j
@Component
public class EmailService {
    @Autowired
    private TemplateEngine templateEngine;
    @Autowired
    private SettingService settingService;


    public EmailProperties getEmailSetting(){
        //这个位置应该先从redis查询设置的一些参数
        //如果redis中不存在当前配置，则查询数据库
        Setting setting = settingService.findByKeySet(SettingConstant.EMAIL_SETTING);
        //if(setting == null)
        String value = setting.getValue();
        if(!StringUtils.isEmpty(value)){
            JSONObject jsonObject = JSONObject.parseObject(value);
            EmailProperties emailProperties = JSONObject.toJavaObject(jsonObject, EmailProperties.class);
            return emailProperties;
        }else {
            return null;
        }
    }


    /**
     * 异步发送邮件
     * @param email 邮箱内容
     */
    @Async
    public void sendTemplateEmail(Email email){
        //设置邮件内容
        try {
            EmailProperties es = getEmailSetting();

            JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();

            //设定邮箱服务器配置
            senderImpl.setUsername(es.getUsername());
            senderImpl.setPassword(es.getPassword());

            Properties props = new Properties();
            props.put("mail.smtp.host", es.getHost());
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.port", es.getPort());
            props.put("mail.smtp.socketFactory.port", es.getPort());
            //鉴权验证
            props.put("mail.smtp.auth", "true");
            MailSSLSocketFactory sf =new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.socketFactory",sf);

            senderImpl.setJavaMailProperties(props);

            //发送html邮件
            MimeMessage mailMessage = senderImpl.createMimeMessage();
            MimeMessageHelper messageHelper = null;
            messageHelper = new MimeMessageHelper(mailMessage,true,"utf-8");

            messageHelper.setTo(email.getTo());
            messageHelper.setFrom(es.getUsername());
            messageHelper.setSubject(email.getTitle());
            String content = email.getContent();
            // true表示HTML格式的邮件
            messageHelper.setText(content,true);//第一个参数应是content
            if(!StringUtils.isEmpty(email.getBbc())) {
                messageHelper.setBcc(email.getBbc());
            }
            Map<String, DataSource> attachments = email.getAttachments();
            if(attachments != null && attachments.size() > 0) {
                for (String fileName : attachments.keySet()) {
                    messageHelper.addAttachment(fileName,attachments.get(fileName));
                }
            }
            // 发送邮件
            log.info("【发送邮件】：开始！");
            senderImpl.send(mailMessage);
            log.info("【发送邮件】：结束！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
            throw new EmailException("发送邮件失败，请检查邮件配置");
        }
    }

    /**
     * 异步发送邮件
     * @param sendTo 发送者
     * @param title 邮件标题
     * @param templateName 邮件模板
     * @param o 模板替换对象
     */
    @Async
    public void sendTemplateEmail(String sendTo, String title, String templateName, Object o){
        try {
            EmailProperties es = getEmailSetting();

            JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();

            //设定邮箱服务器配置
            senderImpl.setHost(es.getHost());
            senderImpl.setPort(es.getPort());
            senderImpl.setUsername(es.getUsername());
            senderImpl.setPassword(es.getPassword());
            Properties props = new Properties();
            props.put("mail.smtp.host", es.getHost());
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.fallback", "false");
            props.put("mail.smtp.port", es.getPort());
            props.put("mail.smtp.socketFactory.port", es.getPort());
            props.put("mail.smtp.auth", "true");
            MailSSLSocketFactory sf =new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.socketFactory",sf);
            senderImpl.setJavaMailProperties(props);
            //发送html邮件
            MimeMessage mailMessage = senderImpl.createMimeMessage();
            MimeMessageHelper messageHelper = null;
            //设置邮件内容
            messageHelper = new MimeMessageHelper(mailMessage,true,"utf-8");

            messageHelper.setTo(sendTo);
            messageHelper.setFrom(es.getUsername());
            messageHelper.setSubject(title);
            Context context = new Context();
            //设置标题和内容
            context.setVariables(ObjectUtil.beanToMap(o));
            // 获取模板html代码
            String content = "";
            if(!StringUtils.isEmpty(templateName)) {
                content = templateEngine.process(templateName, context);
            }
            // true表示HTML格式的邮件
            messageHelper.setText(content, true);//第一个参数应是content
            // 发送邮件
            senderImpl.send(mailMessage);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
            throw new EmailException("发送邮件失败，请检查邮件配置");
        }
    }
}
